# -*- coding: utf-8 -*-
""" Auteur: Anthony Vallée-Dubois """
from Tkinter import *
import Sheet
import Client

""" Cette classe très orientée "interface" sert à gérer l'interface graphique
    associée aux CRC. Il est possible de créer grâce à elle des CRC (Sheets),
    leur donner des responsabilités (actions), des collaborateurs (attributs),
    et d'associer à tout ce beau monde des méta-données.
    Collaborateurs:
        - l'objet Sheet associé
        - l'objet Client du programme
        - les objets Tkinter associés (créés dans printSheet)
    Responsabilités:
        updateSheet(sheet)
        editLeftField(event)
        editRightField(event)
        gotFocus(event)
        printSheet(sheet)
        deleteLeftField(event)
        deleteRightField(event)
"""
class SheetInterface:
    
    def __init__(self,sheet):
        self.sheet = sheet
        self.printSheet(self.sheet)
        self.newDataInsert = 0
    
    """ Cette méthode met à jour un CRC sur le serveur. """
    def updateSheet(self,sheetToUpdate):
        client.server.setObject(sheetToUpdate)
     
    def editLeftField(self,evt):
        
        #print evt.widget.get(1.0, END)
        #print self.leftFieldTypes[self.leftFields.index(evt.widget)][1]
        #print self.leftFieldTypes[self.leftFields.index(evt.widget)][0]
        
        if self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'name':
            self.sheet.name = evt.widget.get(1.0, END)
                
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'sheetMeta':
            self.sheet.metaData[self.leftFieldTypes[self.leftFields.index(evt.widget)][1]] = Sheet.MetaData(evt.widget.get(1.0,END))
        
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'attribute':
            self.sheet.attributes[self.leftFieldTypes[self.leftFields.index(evt.widget)][1]].name = evt.widget.get(1.0,END)
        
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'attributeMeta':
            self.sheet.attributes[self.leftFieldTypes[self.leftFields.index(evt.widget)][2]].metaData[self.leftFieldTypes[self.leftFields.index(evt.widget)][1]].md = evt.widget.get(1.0,END)
            
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'newSheetMeta':
            self.sheet.metaData.append(Sheet.MetaData(evt.widget.get(1.0,END)))
            self.newDataInsert = 1
            
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'newAttributeMeta':
            self.sheet.attributes[self.leftFieldTypes[self.leftFields.index(evt.widget)][1]].metaData.append(Sheet.MetaData(evt.widget.get(1.0,END)))
            self.newDataInsert = 1
                        
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'newAttribute':
            self.sheet.attributes.append(Sheet.Attribute(name = evt.widget.get(1.0,END),metaData = []))
            self.newDataInsert = 1
                        
        self.updateSheet(self.sheet)
        updateSheetList()
        
        if self.newDataInsert == 1:
            self.frame.destroy()
            SheetInterface(self.sheet)
        #window.protocol("WM_WINDOW_DELETE", method)
        return 'break'
        
    def editRightField(self,evt):
        
        #print evt.widget.get(1.0, END)
        #print self.rightFieldTypes[self.rightFields.index(evt.widget)][1]
        #print self.rightFieldTypes[self.rightFields.index(evt.widget)][0]

        if self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'action':
            self.sheet.actions[self.rightFieldTypes[self.rightFields.index(evt.widget)][1]].name = evt.widget.get(1.0,END)
        
        elif self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'argument':
            self.sheet.actions[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].arguments[self.rightFieldTypes[self.rightFields.index(evt.widget)][1]].name = evt.widget.get(1.0,END)

        elif self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'actionMeta':
            self.sheet.actions[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].arguments[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].metaData[self.rightFieldTypes[self.rightFields.index(evt.widget)][1]].md = evt.widget.get(1.0,END)

        elif self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'newActionMeta':
            self.sheet.actions[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].arguments[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].metaData.append(Sheet.MetaData(md = evt.widget.get(1.0,END)))
            self.newDataInsert = 1
            
        elif self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'newActionAttribute':
            self.sheet.actions[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].arguments.append(Sheet.Attribute(name = evt.widget.get(1.0,END)))
            self.newDataInsert = 1
                        
        elif self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'newAction':
            self.sheet.actions.append(Sheet.Action(name = evt.widget.get(1.0,END), arguments = []))
            self.newDataInsert = 1
            
        self.updateSheet(self.sheet)
        
        if self.newDataInsert == 1:
            self.frame.destroy()
            SheetInterface(self.sheet)
        
        return 'break'
        
    def gotFocus(self, evt):
        evt.widget.delete(1.0, END)
        
    def printSheet(self,sheet):
        self.metaDataRow = 0
        self.attributesRow = 0
        self.actionsRow = 0
        self.frame = Toplevel(width=400, height=400)
        
        self.frame.pack_propagate(0)
        self.frame.title("Fiche: " + sheet.name)
        
        self.fieldIndex = 0
        self.buttonIndex = 0
        
        self.leftFieldTypes = []
        self.rightFieldTypes = []
        
        self.count = 0
        self.count1 = 0
        
        self.leftFields = []
        self.leftButtons = []
        
        self.rightFields = []
        self.rightButtons = []
                
        self.leftFields.append(Text(self.frame,height = 1,width = 75))
        self.leftFieldTypes.append(['name',self.count])
        self.leftFields[0].grid(row=0)

        self.buttonIndex = self.buttonIndex + 1
        self.fieldIndex = self.fieldIndex + 1
        
        self.leftFields[0].insert(END, sheet.name)
        
        for i in self.sheet.metaData:
            self.metaDataRow = self.metaDataRow + 1
            self.leftFields.append(Text(self.frame,height = 1,width = 65))
            self.leftFields[self.fieldIndex].insert(END, i)
            self.leftFields[self.fieldIndex].grid(row = self.metaDataRow,sticky = E)
            self.leftFieldTypes.append(['sheetMeta',self.count])
            self.count += 1
            self.fieldIndex = self.fieldIndex + 1   
            
        self.leftFields.append(Text(self.frame,height = 1,width = 65))
        self.leftFields[self.fieldIndex].grid(row = self.metaDataRow +1,sticky = E)
        self.leftFields[self.fieldIndex].insert(END, 'Nouvelle Meta Data')
        self.leftFields[self.fieldIndex].bind("<Button-1>",self.gotFocus)
        self.leftFieldTypes.append(['newSheetMeta',0])
        
        self.fieldIndex += 1
        self.attributesRow = self.metaDataRow + 3
        
        self.count = 0
        
        for i in self.sheet.attributes:
            self.leftFields.append(Text(self.frame,height = 1,width = 75))
            self.leftFields[self.fieldIndex].insert(END,i.name)
            self.leftFields[self.fieldIndex].grid(row=self.attributesRow,column=0, sticky = E)
            self.attributesRow = self.attributesRow + 1
            self.buttonIndex = self.buttonIndex + 1
            self.fieldIndex = self.fieldIndex + 1   
            self.leftFieldTypes.append(['attribute',self.count])
            self.count += 1
            self.count1 = 0
            for j in i.metaData:
                self.leftFields.append(Text(self.frame,height = 1,width = 65))
                self.leftFields[self.fieldIndex].insert(END,j)
                self.leftFields[self.fieldIndex].grid(row=self.attributesRow,column=0, sticky = E)
                self.attributesRow = self.attributesRow + 1
                self.buttonIndex = self.buttonIndex + 1
                self.fieldIndex = self.fieldIndex + 1
                self.leftFieldTypes.append(['attributeMeta',self.count1,self.count -1])
                self.count1 += 1
            self.leftFields.append(Text(self.frame,height = 1,width = 65))
            self.leftFields[self.fieldIndex].grid(row = self.attributesRow,sticky = E)
            self.leftFields[self.fieldIndex].insert(END, 'Nouvelle Meta Data')
            self.leftFields[self.fieldIndex].bind("<Button-1>",self.gotFocus)
            self.leftFieldTypes.append(['newAttributeMeta',self.count-1])
            self.fieldIndex += 1
            self.attributesRow += 3
            
        self.leftFields.append(Text(self.frame,height = 1,width = 75))
        self.leftFields[self.fieldIndex].insert(END, 'Nouvel Attribut')
        self.leftFields[self.fieldIndex].bind("<Button-1>",self.gotFocus)
        self.leftFields[self.fieldIndex].grid(row = self.attributesRow,sticky = E)
        self.leftFieldTypes.append(['newAttribute',0])

        
        self.count = 0
        self.count1 = 0
        self.count2 = 0
        
        self.fieldIndex = 0
        for i in self.sheet.actions:
            self.rightFields.append(Text(self.frame,height = 1,width = 75))
            self.rightFields[self.fieldIndex].insert(END,i.name)
            self.rightFields[self.fieldIndex].grid(row = self.actionsRow,column = 2)
            self.actionsRow = self.actionsRow + 1
            self.fieldIndex += 1
            self.rightFieldTypes.append(['action',self.count])
            self.count += 1
            self.count1 = 0
            self.count2 = 0
            for j in i.arguments:
                self.rightFields.append(Text(self.frame,height =1,width = 65))
                self.rightFields[self.fieldIndex].insert(END,j.name)
                self.rightFields[self.fieldIndex].grid(row = self.actionsRow,column =2, sticky = E)
                self.fieldIndex += 1
                self.rightFieldTypes.append(['argument',self.count1,self.count -1])
                self.count1 += 1
                self.count2 = 0
                self.actionsRow += 1
                for k in j.metaData:
                    self.rightFields.append(Text(self.frame,height =1,width = 55))
                    self.rightFields[self.fieldIndex].insert(END,k)
                    self.rightFields[self.fieldIndex].grid(row = self.actionsRow, column = 2, sticky = E)
                    self.actionsRow = self.actionsRow +1
                    self.fieldIndex += 1
                    self.rightFieldTypes.append(['actionMeta',self.count2,self.count1 -1,self.count -1])
                    self.count2 += 1
                    
                self.rightFields.append(Text(self.frame,height = 1,width = 55))
                self.rightFields[self.fieldIndex].grid(column = 2, row = self.actionsRow,sticky = E)
                self.rightFields[self.fieldIndex].insert(END, 'Nouvelle Meta')
                self.rightFields[self.fieldIndex].bind("<Button-1>",self.gotFocus)
                self.rightFieldTypes.append(['newActionMeta',self.count2-1,self.count1-1, self.count -1])
                self.fieldIndex += 1
                self.actionsRow +=2
                
            self.rightFields.append(Text(self.frame,height = 1,width = 65))
            self.rightFields[self.fieldIndex].grid(column = 2, row = self.actionsRow,sticky = E)
            self.rightFields[self.fieldIndex].insert(END, "Nouvel Attribut d'action")
            self.rightFields[self.fieldIndex].bind("<Button-1>",self.gotFocus)
            self.rightFieldTypes.append(['newActionAttribute',self.count1-1, self.count -1])
            self.fieldIndex += 1
            self.actionsRow += 1
            
        self.rightFields.append(Text(self.frame,height = 1,width = 75))
        self.rightFields[self.fieldIndex].grid(column = 2, row = self.actionsRow,sticky = E)
        self.rightFields[self.fieldIndex].insert(END, "Nouvelle Action")
        self.rightFields[self.fieldIndex].bind("<Button-1>",self.gotFocus)
        self.rightFieldTypes.append(['newAction',self.count-1])
        self.fieldIndex += 1
        self.actionsRow += 1

        for i in self.leftFields:
            i.bind("<Return>", self.editLeftField)
            i.bind("<Delete>", self.deleteLeftField)
        
        for i in self.rightFields:
            i.bind("<Return>", self.editRightField)
            i.bind("<Delete>", self.deleteRightField)
            
    def deleteLeftField(self, evt):
        if self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'sheetMeta':
            self.sheet.metaData.pop(self.leftFieldTypes[self.leftFields.index(evt.widget)][1])
        
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'attribute':
            self.sheet.attributes.pop(self.leftFieldTypes[self.leftFields.index(evt.widget)][1])
        
        elif self.leftFieldTypes[self.leftFields.index(evt.widget)][0] == 'attributeMeta':
            self.sheet.attributes[self.leftFieldTypes[self.leftFields.index(evt.widget)][2]].metaData.pop(self.leftFieldTypes[self.leftFields.index(evt.widget)][1])
                        
        self.updateSheet(self.sheet)
        
        self.frame.destroy()
        SheetInterface(self.sheet)

        return 'break'
    
    def deleteRightField(self, evt):
        
        if self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'action':
            self.sheet.actions.pop(self.rightFieldTypes[self.rightFields.index(evt.widget)][1])
        
        elif self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'argument':
            self.sheet.actions[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].arguments.pop(self.rightFieldTypes[self.rightFields.index(evt.widget)][1])

        elif self.rightFieldTypes[self.rightFields.index(evt.widget)][0] == 'actionMeta':
            self.sheet.actions[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].arguments[self.rightFieldTypes[self.rightFields.index(evt.widget)][2]].metaData.pop(self.rightFieldTypes[self.rightFields.index(evt.widget)][1])
        
        self.updateSheet(self.sheet)
        
        self.frame.destroy()
        SheetInterface(self.sheet)

        return 'break'

""" Cette fonction sert à connecter la classe à l'interface graphique globale. """
def PlugIn(activeClient):
    global client
    client = activeClient
    b = Button(client.frame,text = 'Fiches',command = sheetSelection)
    b.pack()

""" Cette fonction sert à créer la fenêtre nécessaire à la sélection d'un CRC dans la liste,
    à en créer de nouveaux ou à en supprimer. """
def sheetSelection():
    selectionWindow = Toplevel()
    selectionWindow.title("Selection de fiche")
    
    global sheets
    global selectionList
    
    selectionList = Listbox(selectionWindow)
    sheets = Sheet.getSheetList(client)

    selectButton = Button(selectionWindow, text = "Ok")
    deleteButton = Button(selectionWindow, text = "Supprimer")
    newButton = Button(selectionWindow, text = "Nouvelle Fiche")
    
    for i in sheets:
        selectionList.insert(END,i.name)
    
    selectButton.bind("<Button-1>",openSheet)
    deleteButton.bind("<ButtonRelease-1>",deleteSheet)
    newButton.bind("<ButtonRelease-1>",createSheet)
    
    selectionList.pack()
    selectButton.pack()
    deleteButton.pack()
    newButton.pack()

""" Cette fonction sert à créer l'interface graphique nécessaire à la modification
    d'un CRC. """
def openSheet(self):
    selectedIndex = []
    selected = []
    
    for j in selectionList.curselection():
        selectedIndex.append(int(j))

    for h in selectedIndex:
        selected.append(sheets[h])

    for i in selected:
        if isinstance(i, Sheet.Sheet):
            SheetInterface(i)

""" Cette fonction sert à créer un CRC. """
def createSheet(self):
    newSheet = client.server.setObject(Sheet.Sheet(name = 'Nouvelle Fiche'))
    
    sheets.append(newSheet)
    updateSheetList()

""" Cette fonction sert à... bon vous avez deviné """
def deleteSheet(self):
    selectedIndex = []
    selected = []
    
    for j in selectionList.curselection():
        selectedIndex.append(int(j))

    for h in selectedIndex:
        selected.append(sheets[h])
    
    delete = client.server.deleteObjects(selected)
    if delete:
        updateSheetList()

""" Cette fonction met à jour la liste des CRC dans la fenêtre associée. """
def updateSheetList():
    selectionList.delete(0,END)
    sheets = Sheet.getSheetList(client)
    
    for i in sheets:
        selectionList.insert(END, i.name)
    
if __name__ == "__main__":
    sheet = Sheet.Sheet(name = 'WIN', actions = [Sheet.Action(name = 'Action 1', 
                        arguments = [Sheet.Attribute(name = 'Att2', type = 'Attribute2', isArray = False, metaData = [Sheet.MetaData("bla2"),Sheet.MetaData("win2")], version = "testVersionAttribute"),Sheet.Attribute(name = 'Att3', type = 'Attribute3', isArray = False, metaData = [Sheet.MetaData("bla2"),Sheet.MetaData("win2")], version = "testVersionAttribute")],  
                        metaData = [], version = "testVersionAction")],
                        attributes = [Sheet.Attribute(name = 'Att1', type = 'Attribute', isArray = False, metaData = [Sheet.MetaData("bla"),Sheet.MetaData("win")], version = "testVersionAttribute"),Sheet.Attribute(name = 'Att2', type = 'Attribute2', isArray = False, metaData = [Sheet.MetaData("bla"),Sheet.MetaData("win")], version = "testVersionAttribute")], 
                        metaData = [Sheet.MetaData("WINWIN!"),Sheet.MetaData("PRO")], version = "testVersion")
    sheetInterface = SheetInterface(sheet)
    #sheetSelection()